#include <stdio.h>
#include <string.h>

#define Cmd_Section  __attribute__ ((unused,section (".sboot_cmd")))

struct cmd_tbl_s {
	char		*name;		/* Command Name			*/
	int		maxargs;	/* maximum number of arguments	*/
					/* Implementation function	*/
	int		(*cmd)(struct cmd_tbl_s *, int, char *[]);
	char		*usage;		/* Usage message	(short)	*/
};

#define SBOOT_CMD(name,maxargs,cmd,usage) \
struct cmd_tbl_s __sboot_cmd_##name Cmd_Section = {#name, maxargs, cmd, usage}

extern unsigned int __sboot_cmd_start, __sboot_cmd_end;

struct cmd_tbl_s* find_cmd(const char *cmd)
{
	int total_cmds = (__sboot_cmd_end - __sboot_cmd_start) /
			sizeof(struct cmd_tbl_s);
	struct cmd_tbl_s* start = (struct cmd_tbl_s*)__sboot_cmd_start;
	int i;

	for ( i = 0; i < total_cmds; i++) {
		if (!strcmp(cmd, (start + i)->name)) /* match cmd */
			return start + i;
	}

	return NULL;
}

int do_mem_mw(struct cmd_tbl_s *cmdtp, int argc, char *argv[])
{
	unsigned int addr = simple_strtoul(argv[1], NULL, 16);
	unsigned int value = simple_strtoul(argv[2], NULL, 16);

	/* addr must be 4 bytes aligned */
	*((unsigned int*)addr) = value;

	return 0;
}

SBOOT_CMD(mw, 3, do_mem_mw, "mw address value");


int do_mem_md(struct cmd_tbl_s *cmdtp, int argc, char *argv[])
{
	unsigned int addr = simple_strtoul(argv[1], NULL, 16);
	unsigned int length = simple_strtoul(argv[2], NULL, 16);
	int i;

	/* set length to 4 bytes align */
	length = (length + 3) & (~3);

	/* addr must be 4 bytes aligned */
	for (i = 0; i < length; i += 4)
		printf("mem[%x] = 0x%x\n", addr + i,
			*((unsigned int*)(addr + i)));

	return 0;
}

SBOOT_CMD(md, 3, do_mem_md, "md address length");

/*
__sboot_cmd_start = .;
.sboot_cmd : { *(.sboot_cmd) }
__sboot_cmd_end = .;
*/
